home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4.md / devZ8530.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  11KB  |  458 lines

  1. /* 
  2.  * devZ8530.c --
  3.  *
  4.  *    This file provides low-level procedures to manipulate the
  5.  *    Zilog 8530 Serial Communications Controller chip.  In particular,
  6.  *    the code in this file is enough to allow a Z8530 chip to be used
  7.  *    with devTty.c for terminals.
  8.  *
  9.  * Copyright 1989 Regents of the University of California
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose and without
  12.  * fee is hereby granted, provided that the above copyright
  13.  * notice appear in all copies.  The University of California
  14.  * makes no representations about the suitability of this
  15.  * software for any purpose.  It is provided "as is" without
  16.  * express or implied warranty.
  17.  */
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devZ8530.c,v 9.7 92/12/13 18:12:58 mgbaker Exp $ SPRITE (Berkeley)";
  21. #endif /* not lint */
  22.  
  23. #ifndef CLEAN_LOCK
  24. #define CLEAN_LOCK 1
  25. #endif
  26.  
  27. #include <sprite.h>
  28. #include <stdio.h>
  29. #include <mach.h>
  30. #include <sync.h>
  31. #include <z8530.h>
  32. #include <sgtty.h>
  33.  
  34. /*
  35.  * Spin-lock used for synchronization on all Z8530 device registers.
  36.  */
  37.  
  38. static Sync_Semaphore z8530Mutex = Sync_SemInitStatic("Dev:z8530Mutex");
  39.  
  40. /*
  41.  * Tables mapping sgttyb baud-rate values to actual integers.
  42.  */
  43.  
  44. static struct {
  45.     int sgttybVal;            /* Baud value from sgtyb. */
  46.     int baud;                /* Integer baud rate. */
  47. } baudMap[] = {
  48.     {B0, 0},
  49.     {B50, 50},
  50.     {B75, 75},
  51.     {B110, 110},
  52.     {B134, 134},
  53.     {B150, 150},
  54.     {B200, 200},
  55.     {B300, 300},
  56.     {B600, 600},
  57.     {B1200, 1200},
  58.     {B2400, 2400},
  59.     {B4800, 4800},
  60.     {B9600, 9600}, 
  61.     {-1, -1}
  62. };
  63.  
  64. /*
  65.  * Forward declarations to procedures defined in this file:
  66.  */
  67.  
  68. static int        Read();
  69. static void        Write();
  70.  
  71. /*
  72.  *----------------------------------------------------------------------
  73.  *
  74.  * DevZ8530Activate --
  75.  *
  76.  *    This procedure is invoked in order to "activate" one half of a
  77.  *    Z8530 chip.
  78.  *
  79.  * Results:
  80.  *    None.
  81.  *
  82.  * Side effects:
  83.  *    The channel is re-initialized and the receiver is started.
  84.  *
  85.  *----------------------------------------------------------------------
  86.  */
  87.  
  88. void
  89. DevZ8530Activate(ptr)
  90.     Address ptr;
  91. {
  92.     register DevZ8530 *zPtr;
  93.     int speed;
  94.  
  95.     MASTER_LOCK(&z8530Mutex);
  96.     zPtr = (DevZ8530 *) ptr;    /* Information about the device. */
  97.     if (zPtr->flags & Z_CHANNEL_B) {
  98.     Write(zPtr->address, 9, WRITE9_RESET_CHAN_B);
  99.     } else {
  100.     Write(zPtr->address, 9, WRITE9_RESET_CHAN_A);
  101.     }
  102.     MACH_DELAY(10);
  103. #ifndef sun4c
  104.     Write(zPtr->address, 2, zPtr->vector);
  105. #endif
  106.     Write(zPtr->address, 4, WRITE4_PARITY_EVEN + WRITE4_1_STOP + 
  107.                 WRITE4_X16_CLK);
  108.     zPtr->wr3 &= ~WRITE3_RX_ENABLE;
  109.     Write(zPtr->address, 3, zPtr->wr3);
  110.     zPtr->wr5 &= ~(WRITE5_TX_ENABLE | WRITE5_BREAK);
  111.     Write(zPtr->address, 5, zPtr->wr5);
  112.     Write(zPtr->address, 11, WRITE11_TXCLK_BAUD + WRITE11_RXCLK_BAUD);
  113.     speed = ZILOG_SPEED(zPtr->baud);
  114.     Write(zPtr->address, 12, speed);
  115.     Write(zPtr->address, 13, speed >> 8);
  116.     Write(zPtr->address, 14, WRITE14_BAUD_FROM_PCLK);
  117.     zPtr->wr3 |= WRITE3_RX_ENABLE;
  118.     Write(zPtr->address, 3, zPtr->wr3);
  119.     zPtr->wr5 |= (WRITE5_TX_ENABLE | WRITE5_RTS | WRITE5_DTR);
  120.     Write(zPtr->address, 5, zPtr->wr5);
  121.     Write(zPtr->address, 14, WRITE14_BAUD_ENABLE + 
  122.                      WRITE14_BAUD_FROM_PCLK);
  123.     Write(zPtr->address, 0, WRITE0_RESET_ERRORS);
  124.     Write(zPtr->address, 0, WRITE0_RESET_STATUS);
  125.     Write(zPtr->address, 9, WRITE9_MASTER_IE); 
  126.     Write(zPtr->address, 1, WRITE1_RX_IE | WRITE1_TX_IE | WRITE1_EXT_IE); 
  127.     Write(zPtr->address, 0, WRITE0_CLEAR_INTR);
  128.     zPtr->oldRr0 = 0;
  129.     zPtr->flags &= ~Z_INACTIVE;
  130.     MASTER_UNLOCK(&z8530Mutex);
  131. }
  132.  
  133. /*
  134.  *----------------------------------------------------------------------
  135.  *
  136.  * DevZ8530RawProc --
  137.  *
  138.  *    This procedure is called back from the Td module as a raw
  139.  *    control procedure.
  140.  *
  141.  * Results:
  142.  *    The return value is the number of bytes returned to the caller
  143.  *    at outBuffer.
  144.  *
  145.  * Side effects:
  146.  *    Depends on the control operation.  Most likely effect is to
  147.  *    start transferring output data.
  148.  *
  149.  *----------------------------------------------------------------------
  150.  */
  151.  
  152. /* ARGSUSED */
  153. int
  154. DevZ8530RawProc(ptr, operation, inBufSize, inBuffer, outBufSize, outBuffer)
  155.     Address ptr;
  156.     int operation;        /* What to do:  TD_RAW_OUTPUT_READY etc. */
  157.     int inBufSize;        /* Size of input buffer for operation. */
  158.     char *inBuffer;        /* Input buffer. */
  159.     int outBufSize;        /* Size of output buffer for operation. */
  160.     char *outBuffer;        /* Output buffer. */
  161. {
  162.     int result = 0;
  163.     register DevZ8530 *zPtr;
  164.  
  165.     MASTER_LOCK(&z8530Mutex);
  166.     zPtr = (DevZ8530 *) ptr;    /* Our information about device. */
  167.     switch (operation) {
  168.     case TD_RAW_START_BREAK:
  169.         zPtr->wr5 |= WRITE5_BREAK;
  170.         Write(zPtr->address, 5, zPtr->wr5);
  171.         break;
  172.  
  173.     case TD_RAW_STOP_BREAK:
  174.         zPtr->wr5 &= ~WRITE5_BREAK;
  175.         Write(zPtr->address, 5, zPtr->wr5);
  176.         break;
  177.  
  178.     case TD_RAW_SET_DTR:
  179.         zPtr->wr5 |= WRITE5_DTR|WRITE5_RTS;
  180.         Write(zPtr->address, 5, zPtr->wr5);
  181.         break;
  182.  
  183.     case TD_RAW_CLEAR_DTR:
  184.         zPtr->wr5 &= ~(WRITE5_DTR|WRITE5_RTS);
  185.         Write(zPtr->address, 5, zPtr->wr5);
  186.         break;
  187.  
  188.     case TD_RAW_SHUTDOWN:
  189.         Write(zPtr->address, 1, 0);
  190.         MACH_DELAY(10);
  191.         zPtr->flags |= Z_INACTIVE;
  192.         break;
  193.  
  194.     case TD_RAW_OUTPUT_READY:
  195.         if (Read(zPtr->address, 0) & READ0_TX_READY) {
  196.         int c;
  197.  
  198.         c = (*zPtr->outputProc)(zPtr->outputData);
  199.         if (c != -1) {
  200.             Write(zPtr->address, 8, c);
  201.         }
  202.         }
  203.         break;
  204.  
  205.     case TD_RAW_FLUSH_OUTPUT:
  206.         while ((*zPtr->outputProc)(zPtr->outputData) != -1) {
  207.         /* do nothing */
  208.         }
  209.         break;
  210.  
  211.     case TD_RAW_FLOW_CHARS:
  212.         /* Ignore flow-control chars. */
  213.         break;
  214.  
  215.     case TD_RAW_SET_BAUD_RATE: {
  216.         int i, zilogSpeed;
  217.         Td_BaudRate *brPtr;
  218.  
  219.         /*
  220.          * Map the baud rate from an sgttyb constant to an actual
  221.          * number.  Return the value we actually set things to.
  222.          */
  223.  
  224.         brPtr = (Td_BaudRate *) inBuffer;
  225.         for (i = 0; baudMap[i].baud != -1; i++) {
  226.         if (baudMap[i].sgttybVal == brPtr->ospeed) {
  227.             zPtr->baud = baudMap[i].baud;
  228.             break;
  229.         }
  230.         }
  231.         zilogSpeed = ZILOG_SPEED(zPtr->baud);
  232.         Write(zPtr->address, 14, WRITE14_BAUD_FROM_PCLK);
  233.         Write(zPtr->address, 12, zilogSpeed);
  234.         Write(zPtr->address, 13, zilogSpeed >> 8);
  235.         Write(zPtr->address, 14, WRITE14_BAUD_ENABLE +
  236.             WRITE14_BAUD_FROM_PCLK);
  237.  
  238.         /*
  239.          * Fall through to next arm of case to return current
  240.          * settings.
  241.          */
  242.     }
  243.  
  244.     case TD_RAW_GET_BAUD_RATE: {
  245.         int i;
  246.         Td_BaudRate *brPtr;
  247.  
  248.         brPtr = (Td_BaudRate *) outBuffer;
  249.         if (outBufSize >= sizeof(Td_BaudRate)) {
  250.         for (i = 0; baudMap[i].baud != -1; i++) {
  251.             if (baudMap[i].baud == zPtr->baud) {
  252.             brPtr->ispeed = brPtr->ospeed = baudMap[i].sgttybVal;
  253.             result = sizeof(Td_BaudRate);
  254.             }
  255.         }
  256.         }
  257.         break;
  258.     }
  259.     }
  260.     MASTER_UNLOCK(&z8530Mutex);
  261.     return result;
  262. }
  263.  
  264. /*
  265.  *----------------------------------------------------------------------
  266.  *
  267.  * DevZ8530Interrupt --
  268.  *
  269.  *    This procedure is invoked at interrupt level to deal with
  270.  *    a channel of a Z5830 chip.
  271.  *
  272.  * Results:
  273.  *      Always returns TRUE.
  274.  *
  275.  * Side effects:
  276.  *    Input characters may be received, output characters may be
  277.  *    transmitted, and special conditions may be handled.
  278.  *
  279.  *----------------------------------------------------------------------
  280.  */
  281.  
  282. Boolean
  283. DevZ8530Interrupt(clientData)
  284.     ClientData    clientData; /* Information about the device. */
  285. {
  286.     register DevZ8530 *zPtr = (DevZ8530 *) clientData;    
  287.     int rr0, rr1, c;
  288.     int first = 1;
  289.  
  290.     MASTER_LOCK(&z8530Mutex);
  291.  
  292.     if (zPtr->flags & Z_INACTIVE) {
  293.     Write(zPtr->address, 1, 0);
  294.     Write(zPtr->address, 0, WRITE0_RESET_STATUS);
  295.     MASTER_UNLOCK(&z8530Mutex);
  296.     return TRUE;
  297.     }
  298.  
  299.     /*
  300.      * Check the input section of the channel.
  301.      */
  302.  
  303.     while (TRUE) {
  304.     rr0 = Read(zPtr->address, 0);
  305.     if (rr0 & READ0_BREAK) {
  306.         zPtr->flags |= Z_BREAK;
  307.     }
  308.     if (!(rr0 & READ0_RX_READY)) {
  309.         break;
  310.     }
  311.     c = Read(zPtr->address, 8);
  312.     if (first) {
  313.         first = 0;
  314.     } else {
  315.     }
  316.     if (zPtr->flags & Z_BREAK) {
  317.         zPtr->flags &= ~Z_BREAK;
  318.         if (c != 0) {
  319.         printf("Warning:  non-zero break character on %s\n",
  320.             zPtr->name);
  321.         } else {
  322.         c = DEV_TTY_BREAK;
  323.         }
  324.     }
  325.     (*zPtr->inputProc)(zPtr->inputData, c);
  326.     }
  327.  
  328.     rr1 = Read(zPtr->address, 1);
  329.     if (rr1 & (READ1_RX_OVERRUN|READ1_PARITY_ERROR|READ1_FRAMING_ERROR)) {
  330.     if (rr1 & READ1_RX_OVERRUN) {
  331.         printf("Warning: receiver overrun on %s\n", zPtr->name);
  332.     } else if (rr1 & READ1_PARITY_ERROR) {
  333.         printf("Warning: receiver parity error on %s\n", zPtr->name);
  334.     } else {
  335.         printf("Warning: receiver framing error on %s\n", zPtr->name);
  336.     }
  337.     Write(zPtr->address, 0, WRITE0_RESET_ERRORS);
  338.     }
  339.  
  340.     /*
  341.      * Check the output section of the channel.
  342.      */
  343.  
  344.     if (rr0 & READ0_TX_READY) {
  345.     c = (*zPtr->outputProc)(zPtr->outputData);
  346.     if (c == -1) {
  347.         Write(zPtr->address, 0, WRITE0_RESET_TX_INT);
  348.     } else {
  349.         Write(zPtr->address, 8, c);
  350.     }
  351.     }
  352.  
  353.     /*
  354.      * Reset status and interrupt bits.
  355.      */
  356.  
  357.     rr0 &= (READ0_DCD|READ0_CTS|READ0_BREAK);
  358.     if (zPtr->oldRr0 != rr0) {
  359.     Write(zPtr->address, 0, WRITE0_RESET_STATUS);
  360.     zPtr->oldRr0 = rr0;
  361.     }
  362.     Write(zPtr->address, 0, WRITE0_CLEAR_INTR);
  363.     MASTER_UNLOCK(&z8530Mutex);
  364.     return TRUE;
  365. }
  366.  
  367. /*
  368.  *----------------------------------------------------------------------
  369.  *
  370.  * Read --
  371.  *
  372.  *    Read a device register for the Z8530.
  373.  *
  374.  * Results:
  375.  *    The return value is the contents of the given register.
  376.  *
  377.  * Side effects:
  378.  *    None.
  379.  *
  380.  *----------------------------------------------------------------------
  381.  */
  382.  
  383. static int
  384. Read(devPtr, regNumber)
  385.     register volatile DevZ8530Device *devPtr;    /* Location of device
  386.                          * registers. */
  387.     int regNumber;                /* Number of register to
  388.                          * read. */
  389. {
  390.     devPtr->control = regNumber;
  391.     MACH_DELAY(4);
  392.     return devPtr->control;
  393. }
  394.  
  395. /*
  396.  *----------------------------------------------------------------------
  397.  *
  398.  * Write --
  399.  *
  400.  *    Write a device register for the Z8530.
  401.  *
  402.  * Results:
  403.  *    None.
  404.  *
  405.  * Side effects:
  406.  *    The given value is stored into the given register.
  407.  *
  408.  *----------------------------------------------------------------------
  409.  */
  410.  
  411. static void
  412. Write(devPtr, regNumber, value)
  413.     register volatile DevZ8530Device *devPtr;    /* Location of device
  414.                          * registers. */
  415.     int regNumber;                /* Number of register to
  416.                          * read. */
  417.     int value;                    /* Value to write in
  418.                          * register. */
  419. {
  420.     devPtr->control = regNumber;
  421.     MACH_DELAY(4);
  422.     devPtr->control = value;
  423. }
  424.  
  425. /*
  426.  *----------------------------------------------------------------------
  427.  *
  428.  * Dummy routines --
  429.  *
  430.  *    These procedures are needed in the interim while the new
  431.  *    tty driver is being brought up (6/89).  Once it's up, the dbg
  432.  *    module should be changed to make these procedures unnecessary.
  433.  *
  434.  * Results:
  435.  *    None.
  436.  *
  437.  * Side effects:
  438.  *    None.
  439.  *
  440.  *----------------------------------------------------------------------
  441.  */
  442.  
  443. void
  444. Dev_ZilogInit()
  445. {
  446. }
  447.  
  448. int
  449. Dev_ZilogReadReg()
  450. {
  451.     return 0;
  452. }
  453.  
  454. void
  455. Dev_ZilogWriteReg()
  456. {
  457. }
  458.